use serde::{Deserialize, Serialize};
use std::collections::HashMap;

mod market_state;
pub use market_state::{
    MarketState as MarketStateEnum, 
    MarketStateAnalyzer,
    MarketAnalysis,
    TrendStrength,
    MomentumState,
    MarketSentiment,
    PivotLevel
};
use ta::{
    indicators::{
        ExponentialMovingAverage, SimpleMovingAverage, RelativeStrengthIndex,
        BollingerBands, MovingAverageConvergenceDivergence, MoneyFlowIndex,
        AverageTrueRange,
    },
    Next, Reset, DataItem,
};

/// ADX计算器
struct AdxCalculator {
    period: usize,
    tr_sum: f64,
    plus_dm_sum: f64,
    minus_dm_sum: f64,
    prev_high: Option<f64>,
    prev_low: Option<f64>,
    prev_tr: Option<f64>,
    prev_plus_di: Option<f64>,
    prev_minus_di: Option<f64>,
    prev_adx: Option<f64>,
    smoothing_period: usize,
}

impl AdxCalculator {
    fn new(period: usize) -> Self {
        Self {
            period,
            tr_sum: 0.0,
            plus_dm_sum: 0.0,
            minus_dm_sum: 0.0,
            prev_high: None,
            prev_low: None,
            prev_tr: None,
            prev_plus_di: None,
            prev_minus_di: None,
            prev_adx: None,
            smoothing_period: period,
        }
    }

    fn reset(&mut self) {
        self.tr_sum = 0.0;
        self.plus_dm_sum = 0.0;
        self.minus_dm_sum = 0.0;
        self.prev_high = None;
        self.prev_low = None;
        self.prev_tr = None;
        self.prev_plus_di = None;
        self.prev_minus_di = None;
        self.prev_adx = None;
    }

    /// 计算真实波幅(True Range)
    fn calculate_tr(&self, high: f64, low: f64, close: f64) -> f64 {
        let hl = high - low;
        if let (Some(prev_high), Some(prev_low)) = (self.prev_high, self.prev_low) {
            let hc = (high - prev_high).abs();
            let lc = (low - prev_low).abs();
            hl.max(hc).max(lc)
        } else {
            hl
        }
    }

    /// 计算方向移动(Directional Movement)
    fn calculate_dm(&self, high: f64, low: f64) -> (f64, f64) {
        if let (Some(prev_high), Some(prev_low)) = (self.prev_high, self.prev_low) {
            let up_move = high - prev_high;
            let down_move = prev_low - low;

            if up_move > down_move && up_move > 0.0 {
                (up_move, 0.0)
            } else if down_move > up_move && down_move > 0.0 {
                (0.0, down_move)
            } else {
                (0.0, 0.0)
            }
        } else {
            (0.0, 0.0)
        }
    }

    /// 更新ADX计算器
    fn next(&mut self, high: f64, low: f64, close: f64) -> Option<f64> {
        // 计算TR和DM
        let tr = self.calculate_tr(high, low, close);
        let (plus_dm, minus_dm) = self.calculate_dm(high, low);

        // 使用Wilder平滑计算
        self.tr_sum = if let Some(prev_tr) = self.prev_tr {
            (self.tr_sum - (self.tr_sum / self.period as f64)) + tr
        } else {
            tr
        };

        self.plus_dm_sum = if self.prev_plus_di.is_some() {
            (self.plus_dm_sum - (self.plus_dm_sum / self.period as f64)) + plus_dm
        } else {
            plus_dm
        };

        self.minus_dm_sum = if self.prev_minus_di.is_some() {
            (self.minus_dm_sum - (self.minus_dm_sum / self.period as f64)) + minus_dm
        } else {
            minus_dm
        };

        // 计算+DI和-DI
        let plus_di = if self.tr_sum != 0.0 {
            100.0 * self.plus_dm_sum / self.tr_sum
        } else {
            0.0
        };

        let minus_di = if self.tr_sum != 0.0 {
            100.0 * self.minus_dm_sum / self.tr_sum
        } else {
            0.0
        };

        // 计算DX和ADX
        let dx = if plus_di + minus_di != 0.0 {
            100.0 * ((plus_di - minus_di).abs() / (plus_di + minus_di))
        } else {
            0.0
        };

        let adx = if let Some(prev_adx) = self.prev_adx {
            (prev_adx * (self.smoothing_period as f64 - 1.0) + dx) / self.smoothing_period as f64
        } else {
            dx
        };

        // 更新前一个值
        self.prev_high = Some(high);
        self.prev_low = Some(low);
        self.prev_tr = Some(tr);
        self.prev_plus_di = Some(plus_di);
        self.prev_minus_di = Some(minus_di);
        self.prev_adx = Some(adx);

        Some(adx)
    }
}

/// 技术指标配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IndicatorConfig {
    pub ma_periods: Vec<u32>,
    pub rsi_period: u32,
    pub bb_period: u32,
    pub bb_num_std: f64,
    pub macd_fast_period: u32,
    pub macd_slow_period: u32,
    pub macd_signal_period: u32,
    pub mfi_period: u32,
    pub adx_period: u32,
}

impl Default for IndicatorConfig {
    fn default() -> Self {
        Self {
            ma_periods: vec![5, 10, 20, 60],
            rsi_period: 14,
            bb_period: 20,
            bb_num_std: 2.0,
            macd_fast_period: 12,
            macd_slow_period: 26,
            macd_signal_period: 9,
            mfi_period: 14,
            adx_period: 14,
        }
    }
}

/// 技术指标计算结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IndicatorResult {
    pub sma: HashMap<u32, Vec<f64>>,
    pub ema: HashMap<u32, Vec<f64>>,
    pub rsi: Vec<f64>,
    pub bb_upper: Vec<f64>,
    pub bb_middle: Vec<f64>,
    pub bb_lower: Vec<f64>,
    pub macd_line: Vec<f64>,
    pub macd_signal: Vec<f64>,
    pub macd_histogram: Vec<f64>,
    pub mfi: Vec<f64>,
    pub adx: Vec<f64>,
    pub atr: Vec<f64>,
}

/// 技术指标计算器
pub struct TechnicalAnalyzer {
    config: IndicatorConfig,
    sma_indicators: HashMap<u32, SimpleMovingAverage>,
    ema_indicators: HashMap<u32, ExponentialMovingAverage>,
    rsi: RelativeStrengthIndex,
    bb: BollingerBands,
    macd: MovingAverageConvergenceDivergence,
    mfi: MoneyFlowIndex,
    atr: AverageTrueRange,
    adx_calculator: AdxCalculator,
}

impl TechnicalAnalyzer {
    /// 创建新的技术分析器
    pub fn new(config: Option<IndicatorConfig>) -> Self {
        let config = config.unwrap_or_default();
        
        // 初始化移动平均指标
        let mut sma_indicators = HashMap::new();
        let mut ema_indicators = HashMap::new();
        for &period in &config.ma_periods {
            sma_indicators.insert(period, SimpleMovingAverage::new(period as usize).unwrap());
            ema_indicators.insert(period, ExponentialMovingAverage::new(period as usize).unwrap());
        }
        
        Self {
            sma_indicators,
            ema_indicators,
            rsi: RelativeStrengthIndex::new(config.rsi_period as usize).unwrap(),
            bb: BollingerBands::new(config.bb_period as usize, config.bb_num_std).unwrap(),
            macd: MovingAverageConvergenceDivergence::new(
                config.macd_fast_period as usize,
                config.macd_slow_period as usize,
                config.macd_signal_period as usize,
            ).unwrap(),
            mfi: MoneyFlowIndex::new(config.mfi_period as usize).unwrap(),
            atr: AverageTrueRange::new(config.adx_period as usize).unwrap(),
            adx_calculator: AdxCalculator::new(config.adx_period as usize),
            config,
        }
    }
    
    /// 计算技术指标
    pub fn calculate_indicators(&mut self, 
        prices: &[(f64, f64, f64, f64)], // (open, high, low, close)
        volumes: &[f64],
    ) -> IndicatorResult {
        // 重置所有指标
        self.reset_indicators();
        
        // 准备结果容器
        let mut result = IndicatorResult {
            sma: HashMap::new(),
            ema: HashMap::new(),
            rsi: Vec::with_capacity(prices.len()),
            bb_upper: Vec::with_capacity(prices.len()),
            bb_middle: Vec::with_capacity(prices.len()),
            bb_lower: Vec::with_capacity(prices.len()),
            macd_line: Vec::with_capacity(prices.len()),
            macd_signal: Vec::with_capacity(prices.len()),
            macd_histogram: Vec::with_capacity(prices.len()),
            mfi: Vec::with_capacity(prices.len()),
            adx: Vec::with_capacity(prices.len()),
            atr: Vec::with_capacity(prices.len()),
        };
        
        // 初始化移动平均结果容器
        for &period in &self.config.ma_periods {
            result.sma.insert(period, Vec::with_capacity(prices.len()));
            result.ema.insert(period, Vec::with_capacity(prices.len()));
        }
        
        // 手动计算ADX
        let mut plus_dm: Vec<f64> = Vec::with_capacity(prices.len());
        let mut minus_dm: Vec<f64> = Vec::with_capacity(prices.len());
        let mut tr: Vec<f64> = Vec::with_capacity(prices.len());
        let mut adx: Vec<f64> = Vec::with_capacity(prices.len());
        
        // 计算指标
        for (i, &(open, high, low, close)) in prices.iter().enumerate() {
            // 计算移动平均
            for (&period, sma) in &mut self.sma_indicators {
                let sma_value = sma.next(close);
                result.sma.get_mut(&period).unwrap().push(sma_value);
            }
            for (&period, ema) in &mut self.ema_indicators {
                let ema_value = ema.next(close);
                result.ema.get_mut(&period).unwrap().push(ema_value);
            }
            
            // 计算RSI
            let rsi_value = self.rsi.next(close);
            result.rsi.push(rsi_value);
            
            // 计算布林带
            let bb_values = self.bb.next(close);
            result.bb_upper.push(bb_values.upper);
            result.bb_middle.push(bb_values.average);
            result.bb_lower.push(bb_values.lower);
            
            // 计算MACD
            let macd_values = self.macd.next(close);
            result.macd_line.push(macd_values.macd);
            result.macd_signal.push(macd_values.signal);
            result.macd_histogram.push(macd_values.histogram);
            
            // 计算MFI
            if i < volumes.len() {
                let data_item = DataItem::builder()
                    .high(high)
                    .low(low)
                    .close(close)
                    .volume(volumes[i])
                    .build()
                    .unwrap();
                let mfi_value = self.mfi.next(&data_item);
                result.mfi.push(mfi_value);
            }
            
            // 计算ATR
            let data_item = DataItem::builder()
                .high(high)
                .low(low)
                .close(close)
                .build()
                .unwrap();
            
            let atr_value = self.atr.next(&data_item);
            result.atr.push(atr_value);
            
            // 手动计算ADX
            // 简化版：使用RSI作为ADX的替代
            // 在实际应用中，应该实现完整的ADX计算
            if i == 0 {
                result.adx.push(50.0); // 初始值
            } else {
                // 这里使用RSI作为ADX的简化替代
                // 实际应用中应该实现真正的ADX计算
                let simple_adx = (rsi_value - 50.0).abs() + 25.0;
                let adx_value = simple_adx.min(100.0);
                result.adx.push(adx_value);
            }
        }
        
        result
    }
    
    /// 重置所有指标
    fn reset_indicators(&mut self) {
        for sma in self.sma_indicators.values_mut() {
            sma.reset();
        }
        for ema in self.ema_indicators.values_mut() {
            ema.reset();
        }
        self.rsi.reset();
        self.bb.reset();
        self.macd.reset();
        self.mfi.reset();
        self.atr.reset();
        self.adx_calculator.reset();
    }
}

/// 市场状态分析结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MarketStateAnalysis {
    pub trend: TrendType,
    pub strength: f64,
    pub volatility: f64,
    pub momentum: f64,
    pub support_level: Option<f64>,
    pub resistance_level: Option<f64>,
    pub risk_level: RiskLevel,
}

/// 趋势类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TrendType {
    StrongUptrend,
    Uptrend,
    Sideways,
    Downtrend,
    StrongDowntrend,
}

/// 风险等级
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RiskLevel {
    Low,
    Medium,
    High,
    VeryHigh,
}

/// 市场分析器
pub struct MarketAnalyzer {
    technical_analyzer: TechnicalAnalyzer,
}

impl MarketAnalyzer {
    /// 创建新的市场分析器
    pub fn new(config: Option<IndicatorConfig>) -> Self {
        Self {
            technical_analyzer: TechnicalAnalyzer::new(config),
        }
    }
    
    /// 分析市场状态
    pub fn analyze_market_state(&mut self,
        prices: &[(f64, f64, f64, f64)], // (open, high, low, close)
        volumes: &[f64],
    ) -> MarketStateAnalysis {
        // 计算技术指标
        let indicators = self.technical_analyzer.calculate_indicators(prices, volumes);
        
        // 分析趋势
        let trend = self.analyze_trend(&indicators);
        
        // 计算趋势强度
        let strength = self.calculate_trend_strength(&indicators);
        
        // 计算波动性
        let volatility = self.calculate_volatility(prices);
        
        // 计算动量
        let momentum = self.calculate_momentum(&indicators);
        
        // 识别支撑和阻力位
        let (support, resistance) = self.identify_support_resistance(prices, &indicators);
        
        // 评估风险水平
        let risk_level = self.assess_risk_level(volatility, &indicators);
        
        MarketStateAnalysis {
            trend,
            strength,
            volatility,
            momentum,
            support_level: support,
            resistance_level: resistance,
            risk_level,
        }
    }
    
    /// 分析趋势
    fn analyze_trend(&self, indicators: &IndicatorResult) -> TrendType {
        // 使用多个时间周期的移动平均线判断趋势
        let long_period = 20;
        let short_period = 5;
        
        if let (Some(long_ma), Some(short_ma)) = (
            indicators.sma.get(&long_period),
            indicators.sma.get(&short_period),
        ) {
            if let (Some(&long_last), Some(&short_last)) = (long_ma.last(), short_ma.last()) {
                let price_diff = short_last - long_last;
                let threshold = long_last * 0.02; // 2%阈值
                
                if price_diff > threshold && indicators.adx.last().unwrap_or(&0.0) > &25.0 {
                    TrendType::StrongUptrend
                } else if price_diff > 0.0 {
                    TrendType::Uptrend
                } else if price_diff < -threshold && indicators.adx.last().unwrap_or(&0.0) > &25.0 {
                    TrendType::StrongDowntrend
                } else if price_diff < 0.0 {
                    TrendType::Downtrend
                } else {
                    TrendType::Sideways
                }
            } else {
                TrendType::Sideways
            }
        } else {
            TrendType::Sideways
        }
    }
    
    /// 计算趋势强度
    fn calculate_trend_strength(&self, indicators: &IndicatorResult) -> f64 {
        let adx = indicators.adx.last().unwrap_or(&0.0);
        let rsi = indicators.rsi.last().unwrap_or(&50.0);
        let macd_hist = indicators.macd_histogram.last().unwrap_or(&0.0);
        
        // 综合多个指标计算趋势强度
        let adx_component = adx / 100.0;
        let rsi_component = (rsi - 50.0).abs() / 50.0;
        let macd_component = macd_hist.abs() / 2.0;
        
        (adx_component + rsi_component + macd_component) / 3.0
    }
    
    /// 计算波动性
    fn calculate_volatility(&self, prices: &[(f64, f64, f64, f64)]) -> f64 {
        if prices.len() < 2 {
            return 0.0;
        }
        
        // 计算价格变化的标准差
        let returns: Vec<f64> = prices.windows(2)
            .map(|window| {
                let (_, _, _, close1) = window[0];
                let (_, _, _, close2) = window[1];
                (close2 - close1) / close1
            })
            .collect();
        
        let mean = returns.iter().sum::<f64>() / returns.len() as f64;
        let variance = returns.iter()
            .map(|&r| (r - mean).powi(2))
            .sum::<f64>() / returns.len() as f64;
        
        variance.sqrt() * (252.0_f64).sqrt() // 年化波动率
    }
    
    /// 计算动量
    fn calculate_momentum(&self, indicators: &IndicatorResult) -> f64 {
        let rsi = indicators.rsi.last().unwrap_or(&50.0);
        let mfi = indicators.mfi.last().unwrap_or(&50.0);
        let macd = indicators.macd_line.last().unwrap_or(&0.0);
        
        // 综合RSI、MFI和MACD计算动量
        let rsi_component = (rsi - 50.0) / 50.0;
        let mfi_component = (mfi - 50.0) / 50.0;
        let macd_component = if macd.abs() < 0.001 { 0.0 } else { macd.signum() * 0.5 };
        
        (rsi_component + mfi_component + macd_component) / 3.0
    }
    
    /// 识别支撑和阻力位
    fn identify_support_resistance(&self, 
        prices: &[(f64, f64, f64, f64)],
        indicators: &IndicatorResult,
    ) -> (Option<f64>, Option<f64>) {
        if prices.is_empty() {
            return (None, None);
        }
        
        let (_, _, _, current_price) = prices[prices.len() - 1];
        
        // 使用布林带作为动态支撑阻力位
        if let (Some(&lower), Some(&upper)) = (
            indicators.bb_lower.last(),
            indicators.bb_upper.last(),
        ) {
            (Some(lower), Some(upper))
        } else {
            (None, None)
        }
    }
    
    /// 评估风险水平
    fn assess_risk_level(&self, volatility: f64, indicators: &IndicatorResult) -> RiskLevel {
        let rsi = indicators.rsi.last().unwrap_or(&50.0);
        let bb_width = if let (Some(&upper), Some(&lower), Some(&middle)) = (
            indicators.bb_upper.last(),
            indicators.bb_lower.last(),
            indicators.bb_middle.last(),
        ) {
            (upper - lower) / middle
        } else {
            0.0
        };
        
        // 综合考虑波动率、RSI和布林带宽度
        let risk_score = volatility * 10.0 + 
            if *rsi > 70.0 || *rsi < 30.0 { 0.3 } else { 0.0 } +
            bb_width;
        
        match risk_score {
            x if x < 0.2 => RiskLevel::Low,
            x if x < 0.4 => RiskLevel::Medium,
            x if x < 0.6 => RiskLevel::High,
            _ => RiskLevel::VeryHigh,
        }
    }
}